﻿using System;
using System.Collections.Generic;
using System.Text;

namespace RaisingStudio.Data.Common.Expressions
{
    public abstract class AbstractScanner : RaisingStudio.Data.Common.Expressions.IScanner
    {
        private SourceCode sourceCode;
        public SourceCode SourceCode
        {
            get { return sourceCode; }
            protected set { sourceCode = value; }
        }

        protected int _current = 0;
        protected int __current;
        protected char[] current;
        public char[] Current
        {
            get
            {
                if ((__current != _current) || (current == null))
                {
                    current = Content(this._current);
                    __current = _current;
                }
                return current;
            }
        }

        protected int _end;
        protected int __end;
        protected char[] end;
        public char[] End
        {
            get
            {
                if ((__end != _end) || (end == null))
                {
                    end = Content(this._end);
                    __end = _end;
                }
                return end;
            }
        }

        public char[] Content(int index)
        {
            return this.SourceCode.GetContent(index);
        }

        protected int line = 1;
        protected int column = 1;

        protected bool WhiteSpace()
        {
            bool found = false;
            bool bol = (column == 1);
            while (_current < _end && char.IsWhiteSpace(Current[0]))
            {
                if (Current[0] == '\n')
                {
                    line++;
                    column = 0;
                    bol = true;
                }
                found = true;
                _current++;
                column++;
            }
            return found;
        }

        protected void Space()
        {
            while (WhiteSpace())
            {
            }
        }

        public abstract TokenType ReadToken(out SourceLocation tokenBegin, out SourceLocation tokenEnd);


        protected virtual void ReportError(SourceReference sourceReference, string message)
        {
            //System.Diagnostics.Debug.WriteLine(message);
        }

        protected bool IsXDigit(char c)
        {
            return (char.IsDigit(c) ||
                c == 'a' || c == 'A' ||
                c == 'b' || c == 'B' ||
                c == 'c' || c == 'C' ||
                c == 'd' || c == 'D' ||
                c == 'e' || c == 'E' ||
                c == 'f' || c == 'F');
        }
    }
}
